package cn.xsly.ymcc.service.impl;

import cn.xsly.ymcc.constants.Constants;
import cn.xsly.ymcc.domain.MessageBlacklist;
import cn.xsly.ymcc.dto.SmsDto;
import cn.xsly.ymcc.dto.UserRegisterDto;
import cn.xsly.ymcc.exception.GlobleException;
import cn.xsly.ymcc.properties.Smsverify;
import cn.xsly.ymcc.service.IMessageBlacklistService;
import cn.xsly.ymcc.service.IMessageSmsService;
import cn.xsly.ymcc.service.VerifycodeService;

import cn.xsly.ymcc.util.AssertUtil;
import cn.xsly.ymcc.util.StrUtils;

import cn.xsly.ymcc.util.VerifyCodeUtils;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class VerifycodeServiceImpl implements VerifycodeService {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private Smsverify smsverify;
    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;
    @Autowired
    private IMessageSmsService iMessageSmsService;
    @Autowired
    private IMessageBlacklistService blacklistService;


    /*@Override
    public String getImageCode(String imageCodeKey) {
        if (StringUtils.isEmpty(imageCodeKey)) {
            throw new GlobleException("验证码不能为空");
        }
        //生成随机字符验证码
        String randomString = StrUtils.getComplexRandomString(4);
        System.out.println(randomString);
        //存入redis
        redisTemplate.opsForValue().set(imageCodeKey, randomString, 3, TimeUnit.MINUTES);
        //验证码通过base64合成图片
        String verifyCode = VerifyCodeUtils.verifyCode(115, 40, randomString);
        return verifyCode;
    }*/


    @Override
    public void sendSmsCode(UserRegisterDto userRegisterDto) {
        String smsKey = String.format(Constants.SMS_CODE, userRegisterDto.getMobile());
        String smsCode = null;
        SmsDto smsDto = (SmsDto) redisTemplate.opsForValue().get(smsKey);
        Date date = new Date();
        String object = (String) redisTemplate.opsForValue().get(Constants.IMG_CODE+userRegisterDto.getImageCodeKey());
        if(!userRegisterDto.getImageCode().equals(object)){
            System.out.println(userRegisterDto.getImageCode());
            System.out.println(object);
            throw new GlobleException("图形验证码不一致");
        }

        //判断是否进入黑名单
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String ip = requestAttributes.getRequest().getRemoteAddr();
        Boolean aBoolean = blacklistService.selectByIpAndPhone(ip, userRegisterDto.getMobile());
        AssertUtil.isTrue(aBoolean,"你已经被我乱入黑名单");
        if (smsDto != null) {
            boolean b = date.getTime() - smsDto.getSendTime() / 1000 < smsverify.getReTime();
            if (b = true) {
                throw new GlobleException("验证码还未过重发时间");
            }
            smsCode = smsDto.getSmsCode();
        } else {
            smsCode = StrUtils.getRandomString(6);
        }

        SmsDto smsValue = new SmsDto(smsCode, date.getTime());
        //3手机验证码保存redis
        redisTemplate.opsForValue().set(smsKey, smsValue, 10, TimeUnit.MINUTES);
        iMessageSmsService.save("发送验证码", "smsCode", userRegisterDto.getMobile());
        //发送验证码
        /*iVerifyCodeService.smsCode(smsCodeDto);*/
        System.out.println("你的验证码为：" + smsCode + "，请在10分钟之内使用!");//测试
    }

    @Override
    public String getImgCode(String imageCodeKey) {
        String capStr = null, code = null;
        // 生成验证码
        String capText = captchaProducerMath.createText();
        capStr = capText.substring(0, capText.lastIndexOf("@"));
        code = capText.substring(capText.lastIndexOf("@") + 1);
        redisTemplate.opsForValue().set(Constants.IMG_CODE + imageCodeKey, code, 2, TimeUnit.MINUTES);

        String Base64 = VerifyCodeUtils.verifyCode(150, 40, capStr);
        return Base64;
    }


}
